package com.lekang.quartz.task;

import com.lekang.common.utils.DateUtils;
import com.lekang.domain.AppointmentRegistration;
import com.lekang.domain.Contract;
import com.lekang.domain.LeaveRequest;
import com.lekang.service.IAppointmentRegistrationService;
import com.lekang.service.IContractService;
import com.lekang.service.ILeaveRequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.lekang.common.utils.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时任务调度测试
 *
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask
{
    @Autowired
    private IContractService contractService;
    @Autowired
    private IAppointmentRegistrationService appointmentRegistrationService;
    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }
    //    预约登记状态
// 直接定义字符串类型的预约状态（无需数据字典，直接使用）
    private static final String APPOINTMENT_STATUS_PENDING = "待上门";      // 待上门
    private static final String APPOINTMENT_STATUS_COMPLETED = "已完成";     // 已完成
    private static final String APPOINTMENT_STATUS_CANCELLED = "已取消";     // 已取消
    private static final String APPOINTMENT_STATUS_EXPIRED = "已过期";       // 已过期
    public void checkAppointmentExpiration() {
        // 检查当前时间是否在8:00-19:00之间
        if (!isWithinWorkingHours()) {
            System.out.println("[" + DateUtils.getTime() + "]  非工作时间(8:00-19:00)，跳过执行");
            return;
        }

        long startTime = System.currentTimeMillis();
        System.out.println("[" + DateUtils.getTime() + "] 开始执行待上门预约过期检查");

        int totalCount = 0;
        int expiredCount = 0;
        try {
            // 查询所有“待上门”状态的预约
            AppointmentRegistration query = new AppointmentRegistration();
            query.setStatus(APPOINTMENT_STATUS_PENDING);
            List<AppointmentRegistration> appointments = appointmentRegistrationService.selectAppointmentRegistrationList(query);

            totalCount = appointments.size();
            Date currentTime = new Date();
            System.out.println(" 发现待上门预约数量: " + totalCount + "个");

            for (AppointmentRegistration appointment : appointments) {
                // 复用determineAppointmentStatus判断最终状态
                String newStatus = determineAppointmentStatus(appointment, currentTime);
                String originalStatus = appointment.getStatus();

                // 打印时间差（复用getTimeDifferenceMinutes）
                long timeDiff = getTimeDifferenceMinutes(appointment.getAppointmentTime(), currentTime);
                System.out.println(" 预约ID: " + appointment.getId() +
                        "，预约时间: " + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", appointment.getAppointmentTime()) +
                        "，时间差: " + timeDiff + "分钟");

                // 状态变化时才更新
                if (!newStatus.equals(originalStatus)) {
                    appointment.setStatus(newStatus);
                    appointmentRegistrationService.updateAppointmentRegistration(appointment);
                    expiredCount++;
                    System.out.println(" 预约ID: " + appointment.getId() + " 状态更新为: " + newStatus);
                }
            }
        } catch (Exception e) {
            System.err.println("[" + DateUtils.getTime() + "] 检查待上门预约过期时出错：" + e.getMessage());
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        System.out.println("[" + DateUtils.getTime() + "] 完成待上门预约过期检查，共处理" + totalCount + "条预约，过期" + expiredCount + "条，耗时" + (endTime - startTime) + "ms");
    }


    /**
     * 核心逻辑：判断预约应有的状态
     * @param appointment 单个预约信息
     * @param currentTime 当前系统时间
     * @return 最终应有的状态（字符串类型）
     */
    private String determineAppointmentStatus(AppointmentRegistration appointment, Date currentTime) {
        // 若预约时间为空，保持原状态（默认“待上门”）
        if (appointment.getAppointmentTime() == null) {
            return appointment.getStatus() != null ? appointment.getStatus() : APPOINTMENT_STATUS_PENDING;
        }

        // 若当前时间还没到预约时间，保持“待上门”
        if (currentTime.before(appointment.getAppointmentTime())) {
            return APPOINTMENT_STATUS_PENDING;
        }

        // 计算当前时间与预约时间的差值（毫秒）
        long timeDiffMillis = currentTime.getTime() - appointment.getAppointmentTime().getTime();
        long oneHourMillis = 60 * 60 * 1000; // 1小时的毫秒数

        // 若超过预约时间1小时以上，标记为“已过期”
        if (timeDiffMillis > oneHourMillis) {
            return APPOINTMENT_STATUS_EXPIRED;
        }

        // 其他情况（如超过预约时间但未满1小时），保持原状态
        return appointment.getStatus() != null ? appointment.getStatus() : APPOINTMENT_STATUS_PENDING;
    }




    private boolean isWithinWorkingHours() {
        Date currentTime = new Date();
        String currentHourMinute = DateUtils.parseDateToStr("HH:mm", currentTime);
        String[] timeParts = currentHourMinute.split(":");

        int currentHour = Integer.parseInt(timeParts[0]);
        int currentMinute = Integer.parseInt(timeParts[1]);
        int totalMinutes = currentHour * 60 + currentMinute; // 转换为当天的总分钟数

        int workStartMinutes = 8 * 60;  // 8:00 = 480分钟
        int workEndMinutes = 22 * 60;    // 22:00 = 1140分钟

        return totalMinutes >= workStartMinutes && totalMinutes <= workEndMinutes;
    }
    /**
     * 计算两个时间的差值（分钟）
     * @param startTime 开始时间（预约时间）
     * @param endTime 结束时间（当前时间）
     * @return 时间差（分钟），不足1分钟按0计算
     */
    private long getTimeDifferenceMinutes(Date startTime, Date endTime) {
        if (startTime == null || endTime == null) {
            return 0;
        }
        long diffMillis = endTime.getTime() - startTime.getTime();
        return diffMillis / (60 * 1000); // 毫秒转分钟
    }

    private static final String STATUS_PENDING = "未生效";      // 未生效
    private static final String STATUS_ACTIVE = "生效中";       // 生效中
    private static final String STATUS_EXPIRED = "已过期";      // 已过期
    private static final String STATUS_INVALID = "已失效";      // 已失效
    public void checkContractStatus(){
        System.out.println("========================================");
        System.out.println("[" + DateUtils.getTime() + "]  开始执行合同状态检查定时任务");

        long startTime = System.currentTimeMillis();
        try {
            // 查询所有合同
            List<Contract> contracts = contractService.selectContractList(new Contract());
            System.out.println("📊 数据库中共有合同数量: " + contracts.size() + "个");

            // 过滤出非"已失效"状态的合同（只处理未失效的合同）
            List<Contract> validContracts = contracts.stream()
                    .filter(contract -> !STATUS_INVALID.equals(contract.getContractStatus()))
                    .collect(Collectors.toList());

            int totalCount = validContracts.size();
            int updatedCount = 0;
            Date currentTime = new Date();

            System.out.println("🔍 发现非已失效合同数量: " + totalCount + "个");
            System.out.println("⏰ 当前系统时间: " + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", currentTime));

            if (validContracts.isEmpty()) {
                System.out.println("ℹ️ 没有需要检查的合同，跳过处理");
                return;
            }

            for (Contract contract : validContracts) {
                String originalStatus = contract.getContractStatus();
                String newStatus = determineContractStatus(contract, currentTime);

                System.out.println("📋 合同检查 - ID: " + contract.getId() +
                        ", 名称: " + contract.getContractName() +
                        ", 当前状态: " + originalStatus +
                        ", 计算状态: " + newStatus +
                        ", 开始时间: " + DateUtils.parseDateToStr("yyyy-MM-dd", contract.getStartDate()) +
                        ", 结束时间: " + (contract.getEndDate() == null ? "空" : DateUtils.parseDateToStr("yyyy-MM-dd", contract.getEndDate())));

                // 状态变化时才更新
                if (!newStatus.equals(originalStatus)) {
                    contract.setContractStatus(newStatus);
                    int result = contractService.updateContract(contract);

                    if (result > 0) {
                        updatedCount++;
                        System.out.println("✅ 状态更新成功 - ID: " + contract.getId() +
                                ", 状态变更: " + originalStatus + " → " + newStatus);
                    } else {
                        System.out.println("❌ 状态更新失败 - ID: " + contract.getId());
                    }
                } else {
                    System.out.println("➡️ 状态无需更新 - ID: " + contract.getId());
                }
            }
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;

            System.out.println("🎯 任务执行完成");
            System.out.println("📈 处理统计 - 总合同: " + totalCount + "个, 更新: " + updatedCount + "个");
            System.out.println("⏱️ 任务执行时间: " + executionTime + "ms");
            System.out.println("========================================");

        } catch (Exception e) {
            System.err.println("💥 合同状态检查执行失败: " + e.getMessage());
            e.printStackTrace();
            System.out.println("========================================");
        }
    }

    /**
     * 判断合同状态逻辑（使用字符串状态值）
     */
    private String determineContractStatus(Contract contract, Date currentTime) {
        // 1. 如果合同有解除时间，直接标记为"已失效"
        if (contract.getTerminationTime() != null) {
            return STATUS_INVALID;
        }

        // 2. 当前时间 < 合同开始时间 → "未生效"
        if (currentTime.before(contract.getStartDate())) {
            return STATUS_PENDING;
        }

        // 3. 合同结束时间不为空，且当前时间 > 结束时间 → "已过期"
        if (contract.getEndDate() != null && currentTime.after(contract.getEndDate())) {
            return STATUS_EXPIRED;
        }

        // 4. 当前时间在开始时间之后，且在结束时间之前（或无结束时间）→ "生效中"
        if (currentTime.after(contract.getStartDate()) &&
                (contract.getEndDate() == null || currentTime.before(contract.getEndDate()))) {
            return STATUS_ACTIVE;
        }

        // 默认保持原状态，无状态时默认为"未生效"
        return contract.getContractStatus() != null ? contract.getContractStatus() : STATUS_PENDING;
    }

    @Autowired
    private ILeaveRequestService leaveRequestService;



    // -------------------------- 请假任务 --------------------------
    private static final String LEAVE_INIT_STATUS = "已批准"; // 抽取为常量，便于后续修改
    private static final String STATUS_ON_LEAVE = "请假中";
    private static final String STATUS_OVERDUE = "超时未归";
    private static final String STATUS_RETURNED = "已返回";

    public void checkLeaveStatus() {
        // 新增：工作时间限制（与预约任务一致，8:00-19:00）
        if (!isWithinWorkingHours()) {
            System.out.println("[" + DateUtils.getTime() + "]  非工作时间(8:00-19:00)，跳过执行");
            return;
        }

        System.out.println("========================================");
        System.out.println("[" + DateUtils.getTime() + "] 🚀 开始执行请假状态检查");

        long startTime = System.currentTimeMillis();
        Date currentTime = new Date();

        try {
            // 修复：使用常量查询初始状态，便于维护
            LeaveRequest query = new LeaveRequest();
            query.setLeaveStatus(LEAVE_INIT_STATUS);
            List<LeaveRequest> leaveList = leaveRequestService.selectLeaveRequestList(query);
            System.out.println("📊 待监控的[" + LEAVE_INIT_STATUS + "]请假记录: " + leaveList.size() + "条");

            int updatedCount = 0;
            System.out.println("⏰ 当前时间: " + DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", currentTime));

            if (leaveList.isEmpty()) {
                System.out.println("ℹ️ 无待处理记录，任务结束");
                return;
            }

            for (LeaveRequest leave : leaveList) {
                try { // 新增：单个请假记录异常捕获
                    String newStatus = determineStatus(leave, currentTime);
                    String oldStatus = leave.getLeaveStatus() != null ? leave.getLeaveStatus() : "未设置";

                    // 修复：避免null导致的日志报错
                    String elderlyName = leave.getElderlyName() != null ? leave.getElderlyName() : "未知老人";
                    String expectedEndStr = leave.getExpectedEndTime() != null
                            ? DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", leave.getExpectedEndTime())
                            : "未设置";
                    String actualEndStr = leave.getActualEndTime() != null
                            ? DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", leave.getActualEndTime())
                            : "未填写";

                    System.out.println("📋 记录ID: " + leave.getId() +
                            ", 老人: " + elderlyName +
                            ", 预计返回: " + expectedEndStr +
                            ", 实际返回: " + actualEndStr +
                            ", 状态变更: " + oldStatus + " → " + newStatus);

                    if (!newStatus.equals(oldStatus)) {
                        leave.setLeaveStatus(newStatus);
                        int result = leaveRequestService.updateLeaveRequest(leave);
                        if (result > 0) {
                            updatedCount++;
                            System.out.println("✅ 已更新为: " + newStatus);
                        } else {
                            System.out.println("❌ 更新失败");
                        }
                    } else {
                        System.out.println("➡️ 状态不变");
                    }
                } catch (Exception e) {
                    System.err.println(" 处理请假记录ID: " + leave.getId() + " 时出错：" + e.getMessage());
                }
            }

            long endTime = System.currentTimeMillis();
            System.out.println("🎯 任务完成 - 总检查: " + leaveList.size() + "条, 成功更新: " + updatedCount + "条");
            System.out.println("⏱️ 耗时: " + (endTime - startTime) + "ms");
            System.out.println("========================================");

        } catch (Exception e) {
            System.err.println("💥 请假任务执行失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private String determineStatus(LeaveRequest leave, Date currentTime) {
        // 1. 已填写实际返回时间 → 已返回
        if (leave.getActualEndTime() != null) {
            return STATUS_RETURNED;
        }

        // 2. 未填写实际返回时间 → 处理预计返回时间
        Date expectedEnd = leave.getExpectedEndTime();
        if (expectedEnd == null) {
            // 新增：打印日志，明确无预计返回时间的记录
            System.out.println(" 请假记录ID: " + leave.getId() + " 未设置预计返回时间，默认标记为请假中");
            return STATUS_ON_LEAVE;
        }

        // 3. 时间对比
        if (currentTime.compareTo(expectedEnd) <= 0) {
            return STATUS_ON_LEAVE;
        } else {
            return STATUS_OVERDUE;
        }
    }


}
